package CamposDePotencial;

import java.io.IOException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import javax.vecmath.Point3d;

import comunicacion.Conector;
import estrategia.ParametrosPotenciales;
import estrategia.Predictor;
import estrategia.Utiles;
import estrategia.Vector;


public class EstrategiaCampoPotencial {

	private HashMap<Integer, ArrayList<CampoPotencial>> campos;
	private FabricaPotenciales fabrica;
	private Conector conector;
	private Utiles utiles;
	
	/**
	 * @param conector
	 */
	public EstrategiaCampoPotencial(Objetivo objetivo, ArrayList<Integer> objetos, Utiles u, Conector conector, Predictor predictor) {
		fabrica = new FabricaPotenciales(objetivo, objetos, predictor);
		utiles = u;
		this.conector = conector;
		campos = fabrica.obtenerCampos(conector);
	}
	
	
	public Vector SumarFuerzas(Point3d mipos) throws IOException {
		Vector resultante = new Vector(0, 0);
		Iterator<Integer> iterObjetos = campos.keySet().iterator();
		
		while (iterObjetos.hasNext()) {
			int idObjeto = iterObjetos.next();
			Iterator<CampoPotencial> iterCamposObjeto = campos.get(idObjeto).iterator();
			
			while (iterCamposObjeto.hasNext()) {
				CampoPotencial campo = iterCamposObjeto.next();
				Vector fCampo = campo.obtenerFuerza(mipos);
				resultante = utiles.sumaVectores(resultante, fCampo);
			}
		}
		
		resultante.setMagnitud(Math.abs(resultante.getMagnitud()));
		
		return resultante;
	}
	
	
	public Point3d mapearPuntoDestino(Point3d mipos, Point3d objetivo, Vector resultante) {
		Point3d destino = new Point3d();
		double gananciaMagnitudDistancia = ParametrosPotenciales.GANANCIA_MAGNITUD_DISTANCIA;
		double mag = 0;
		 
		if (resultante.getMagnitud() >= 0.2) {
			
			//if (resultante.getMagnitud() <= 60) {
			mag = resultante.getMagnitud();
			//} else {
			//	mag = 60;
			//}
			//double mag = Math.sqrt(resultante.getMagnitud());
			//destino.x = (mag)*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.x;
			//destino.y = (mag)*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.y;
			
			destino.x = (mag)*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.x;
			destino.y = (mag)*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.y;
			//System.out.println("El cos es: " + resultante.getMagnitud()*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + " el seno es: " + resultante.getMagnitud()*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia);
			
		} else {
			destino = objetivo;
		}
		
		return destino;
	}
	
	public Point3d getDestino(Point3d mipos, Point3d objetivo) throws IOException {
		Vector resultante = SumarFuerzas(mipos);
		
		Point3d destino = mapearPuntoDestino(mipos, objetivo, resultante); 
		//System.out.println("La direccion es = " + resultante.getDireccion() + " la magnitud es = " + resultante.getMagnitud());
		//System.out.println("El punto destino es: " + destino.x + " , " + destino.y);
		//System.out.println("Mi pos es: " + mipos.x + " , " + mipos.y);
		
		return destino;
	}
	
	public void eliminarCampo(int idObjeto) {
		fabrica.eliminarCampo(idObjeto);
		campos = fabrica.obtenerCampos(conector);
	}
	
}
